package cc.verywell.pureblock.func.node;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;

/**
* 
* Copyright © 2019 TanYaqiu. All rights reserved.
* @author TanYaqiu 
* @address flat 601
* @date 2019年5月5日 下午7:38:34
*/
public abstract class NodeAlias {

	static public NodeAlias map = new NodeAlias() {
		@Override
		public Alias get(KeyShell key) {
			return null;
		}
	};

	abstract public Alias get(KeyShell key);
	public OK put(KeyShell key, String alias) {return OK.FAILD;};
	
	enum OK{
		OK,STORED,DUMPLCATED,FAILD
	}
	
	static final public class Alias{
		final private String alias;
		final private String extra;
		public Alias(String alias, String extra) {
			this.alias = alias;
			this.extra = extra;
		}
		public String getAlias() {
			return alias;
		}
		public String getExtra() {
			return extra;
		}
		@Override
		public String toString() {
			if(alias==null) {
				if(extra==null) {
					return "";
				}else {
					return "-"+extra;
				}
			}else {
				if(extra==null) {
					return alias;
				}else {
					return alias+"-"+extra;
				}
			}
		}
		@Override
		public int hashCode() {
			if(alias!=null)return alias.hashCode();
			if(extra!=null)return extra.hashCode();
			return 0;
		}
		@Override
		public boolean equals(Object obj) {
			if(obj==this)return true;
			if(obj!=null && obj.getClass()==this.getClass()) {
				Alias a = (Alias)obj;
				if(alias!=null?!alias.equals(a.alias):a.alias!=null)return false;
				if(extra!=null?!extra.equals(a.extra):a.extra!=null)return false;
				return true;
			}
			return false;
		}
	}
	
	static public class TempArrayAlias extends NodeAlias{
		private LinkedList<Alias> array;
		private Map<KeyShell,Alias> map;
		public TempArrayAlias(String... alias) {
			HashSet<String> set = new HashSet<>(alias.length);
			this.array = new LinkedList<>();
			int count = 0;
			for (String s : alias) {
				if(set.add(s)) {
					this.array.add(new Alias(s,null));
				}else {
					this.array.add(new Alias(s,String.valueOf(++count)));
				}
			}
			this.map = new HashMap<>(this.array.size());
		}
		@Override
		public Alias get(KeyShell key) {
			if(array==null)
				return map.get(key);
			LinkedList<Alias> array = this.array;
			if(array!=null) {
				synchronized (array) {
					Alias a = map.get(key);
					if(a!=null)return a;
					if(array.isEmpty()) {
						this.array=null;
						return a;
					}
					a = array.removeFirst();
					map.put(key, a);
					return a;
				}
			}
			return null;
		}
	}
	
}
